package com.xbts.screen.service.impl;

import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.xbts.common.core.utils.DateUtils;
import com.xbts.common.core.enums.DateTypeEnum;
import com.xbts.common.core.domain.WeProduceInformationStatistics;
import com.xbts.screen.domain.vo.*;
import com.xbts.screen.mapper.ScreenMapper;
import com.xbts.screen.service.ICutidMapperService;
import com.xbts.screen.service.IScreenServer;
import com.xbts.screen.service.IWeProduceInformationStatisticsService;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.text.DecimalFormat;
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAdjusters;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

/**
 * @author : llk
 * @Date: 2023/12/29 15:34
 */
@Service
public class ScreenServerImpl implements IScreenServer {

    @Resource
    private ScreenMapper screenMapper;

    @Resource
    private ICutidMapperService cutidMapperService;

    private static final DecimalFormat decimalFormat = new DecimalFormat("#.##");

    @Resource
    private IWeProduceInformationStatisticsService weProduceInformationStatisticsService;

    private final static String ORDER_AREA_FIELD = "orderArea"; // 接单面积
    private final static String ORDER_TIME_FIELD = "orderTime"; // 接单日期
    private final static String FACTORY_NAME_FIELD = "factoryName"; // 厂房名称
    private final static String TARGET_FIELD = "target"; // 目标


    @DS("wecan")
    @Override
    public BusinessInformationVO businessInformation() {
        Double value = screenMapper.monthlyOrderTargetArea();
        // 目标
        List<Double> targetList = IntStream.range(0, 3)
                .mapToDouble(i -> value)
                .boxed()
                .collect(Collectors.toList());

        // 昨天
        List<String> yesterdayDate = DateUtils.getYesterdayDate();
        List<Map> data1 = screenMapper.getOrderByTime(yesterdayDate.get(0), yesterdayDate.get(1), null);

        // 本周
        List<String> currentWeekDate = DateUtils.getCurrentWeek();
        List<Map> data2 = screenMapper.getOrderByTime(currentWeekDate.get(0), currentWeekDate.get(1), null);

        // 本月
        List<String> currentMonthDate = DateUtils.getCurrentMonth();
        List<Map> data3 = screenMapper.getOrderByTime(currentMonthDate.get(0), currentMonthDate.get(1), null);

        // 订单
        List<Double> orderList = new ArrayList<>(3);
        orderList.add(getSumOrderArea(data1));
        orderList.add(getSumOrderArea(data2));
        orderList.add(getSumOrderArea(data3));

        // 时间
        List<String> timeList = new ArrayList<>(3);
        timeList.add("昨天");
        timeList.add("本周");
        timeList.add("本月");

        BusinessInformationVO businessInformationVO = new BusinessInformationVO();
        businessInformationVO.setOrderList(orderList);
        businessInformationVO.setTimeList(timeList);
        businessInformationVO.setTargetList(targetList);

        return businessInformationVO;
    }

    @Override
    public List<QualityInformationVO> qualityInformation() {
        List<QualityInformationVO> qualityInformationVOS = new ArrayList<>(3);
        // 获取当前日期和时间
        LocalDateTime now = LocalDateTime.now();
        // 获取当天的开始时间和结束时间
        LocalDateTime todayStart = LocalDateTime.of(now.toLocalDate(), LocalTime.MIN);
        LocalDateTime todayEnd = LocalDateTime.of(now.toLocalDate(), LocalTime.MAX);

        // 格式化LocalDateTime
        String todayStartStr = todayStart.format(DateTimeFormatter.ofPattern(DateUtils.YYYY_MM_DD_HH_MM_SS));
        String todayEndStr = todayEnd.format(DateTimeFormatter.ofPattern(DateUtils.YYYY_MM_DD_HH_MM_SS));
        // 当天
        Map currentDay = screenMapper.qualityInformation(todayStartStr, todayEndStr);
        // 昨天
        List<String> yesterdayDate = DateUtils.getYesterdayDate();
        Map lastDay = screenMapper.qualityInformation(yesterdayDate.get(0), yesterdayDate.get(1));
        // 本周
        List<String> currentWeekDate = DateUtils.getCurrentWeek();
        Map currentWeek = screenMapper.qualityInformation(currentWeekDate.get(0), currentWeekDate.get(1));
        // 上周
        List<String> lastWeekDate = DateUtils.getLastWeek();
        Map lastWeek = screenMapper.qualityInformation(lastWeekDate.get(0), lastWeekDate.get(1));
        // 本月
        List<String> currentMonthDate = DateUtils.getCurrentMonth();
        Map currentMonth = screenMapper.qualityInformation(currentMonthDate.get(0), currentMonthDate.get(1));
        // 上月
        List<String> lastMonthDate = DateUtils.getCurrentMonth();
        Map lastMonth = screenMapper.qualityInformation(lastMonthDate.get(0), lastMonthDate.get(1));

        // 封装返回对象 天
        QualityInformationVO dayQuality = new QualityInformationVO();
        dayQuality.setDateType(DateTypeEnum.DAY);
        dayQuality.setCurrentMonthQualificationRate(getQualityInfo(currentDay));
        dayQuality.setLastMonthQualificationRate(getQualityInfo(lastDay));
        dayQuality.setTrend(getQualityInfo(currentDay).compareTo(getQualityInfo(lastDay)));
        // 封装返回对象 周
        QualityInformationVO weekQuality = new QualityInformationVO();
        weekQuality.setDateType(DateTypeEnum.WEEK);
        weekQuality.setCurrentMonthQualificationRate(getQualityInfo(currentWeek));
        weekQuality.setLastMonthQualificationRate(getQualityInfo(lastWeek));
        weekQuality.setTrend(getQualityInfo(currentWeek).compareTo(getQualityInfo(lastWeek)));
        // 封装返回对象 月
        QualityInformationVO monthQuality = new QualityInformationVO();
        monthQuality.setDateType(DateTypeEnum.MONTH);
        monthQuality.setCurrentMonthQualificationRate(getQualityInfo(currentMonth));
        monthQuality.setLastMonthQualificationRate(getQualityInfo(lastMonth));
        monthQuality.setTrend(getQualityInfo(currentMonth).compareTo(getQualityInfo(lastMonth)));

        qualityInformationVOS.add(dayQuality);
        qualityInformationVOS.add(weekQuality);
        qualityInformationVOS.add(monthQuality);
        return qualityInformationVOS;
    }

    @Override
    @DS("wecan")
    public StatisticalChartVO produceInformation() {
        Map<String, Object> map = new HashMap<>();
        Date now = new Date();
        String endTime = DateUtils.getTime();
        String startTime = DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, DateUtils.addDays(now, -9));
        // 获取最近十天的所有数据
        List<WeProduceInformationIndexStatisticsVO> voList = screenMapper.produceInformation(startTime, endTime);
        Map<String, WeProduceInformationIndexStatisticsVO> voMap = voList.stream().collect(Collectors.toMap(WeProduceInformationIndexStatisticsVO::getStorageTime, v -> v));
        // 横坐标
        ArrayList<Object> dateList = new ArrayList<>();
        // 数据集合
        ArrayList<Object> produceList = new ArrayList<>();
        for (int i = 9; i >= 0; i--) {
            String dateStr = DateUtils.parseDateToStr(DateUtils.MM_DD, DateUtils.addDays(now, -i));
            String keyStr = DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, DateUtils.addDays(now, -i));
            dateList.add(dateStr);
            if (voMap.containsKey(keyStr)) {
                produceList.add(voMap.get(keyStr).getStorageArea());
            } else {
                produceList.add(0);
            }
        }
        // 封装并返回
        StatisticalChartVO chartVO = new StatisticalChartVO();
        chartVO.setKeys(dateList);
        ArrayList<StatisticalChartValueVO> values = new ArrayList<>();
        StatisticalChartValueVO chartValueVO = new StatisticalChartValueVO();
        chartValueVO.setName("产能");
        chartValueVO.setData(produceList);
        values.add(chartValueVO);
        chartVO.setValues(values);
        return chartVO;
    }

    @Override
    @DS("wecan")
    public Object test() {
        return cutidMapperService.list();
    }

    @DS("wecan")
    @Override
    public Object businessInformationDetail(DateTypeEnum dateTypeEnum) {

        List<String> dateList = new ArrayList<>(2);
        switch (dateTypeEnum) {
            case DAY:
                dateList = DateUtils.getTodayDate();
                break;
            case WEEK:
                dateList = DateUtils.getCurrentWeek();
                break;
            case MONTH:
                dateList = DateUtils.getCurrentMonth();
                break;
            default:
                break;
        }
        List<Map> dataList = screenMapper.businessInformationDetail(dateList.get(0), dateList.get(1));
        List<Double> targetList = new ArrayList<>();
        List<Double> orderAreaList = new ArrayList<>();
        List<String> factoryNameList = new ArrayList<>();
        BusinessInformationDetailVO vo = new BusinessInformationDetailVO(targetList, orderAreaList, factoryNameList);

        for (Map map : dataList) {
            // 目标
            Object target = map.getOrDefault(TARGET_FIELD, "0");
            // 订单
            Object orderArea = map.getOrDefault(ORDER_AREA_FIELD, 0D);
            // 厂区名
            String factoryName = (String) map.getOrDefault(FACTORY_NAME_FIELD, "");

            targetList.add(Double.parseDouble(decimalFormat.format(target)));
            orderAreaList.add(Double.parseDouble(decimalFormat.format(orderArea)));
            factoryNameList.add(factoryName);
        }
        return vo;
    }

    @DS("wecan")
    @Override
    public Object businessInformationFactoryDetail(DateTypeEnum dateTypeEnum, String factoryName) {
        LocalDate startDate = null;
        LocalDate endDate = null;
        LocalDate today = LocalDate.now();
        List<Map> dayData = new ArrayList<>();

        switch (dateTypeEnum) {
            case WEEK:
                startDate = today.minusWeeks(4).with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY));
                endDate = today.with(TemporalAdjusters.previousOrSame(DayOfWeek.SUNDAY));
                dayData = screenMapper.getOrderByTime(startDate.toString(), endDate.toString(), factoryName);
                break;
            case MONTH:
                startDate = LocalDate.now().withDayOfYear(1);
                // 获取今年的最后一天
                endDate = LocalDate.now().withDayOfYear(LocalDate.now().lengthOfYear());
                dayData = screenMapper.getOrderByMonth(startDate.toString(), endDate.toString(), factoryName);
                break;
            default:
                startDate = today.withDayOfMonth(1);
                endDate = today.withDayOfMonth(today.lengthOfMonth());
                dayData = screenMapper.getOrderByTime(startDate.toString(), endDate.toString(), factoryName);
                break;
        }
        if (dayData.isEmpty()) {
            return new BusinessInformationDetailByFactoryVO();
        }

        Map<String, Double> dataMap = dayData.stream()
                .collect(Collectors.toMap(e -> e.get(ORDER_TIME_FIELD).toString(),
                        e -> Double.parseDouble(e.get(ORDER_AREA_FIELD).toString())));

        List<String> dateTimeList = new ArrayList<>(); // 日期数组
        List<Double> targetList = new ArrayList<>(); // 目标
        List<Double> valueList = new ArrayList<>(); // 日期对应的值数组

        BusinessInformationDetailByFactoryVO businessInformationDetailVO = new BusinessInformationDetailByFactoryVO();
        businessInformationDetailVO.setTargetList(targetList);
        businessInformationDetailVO.setDateTimeList(dateTimeList);
        businessInformationDetailVO.setValueList(valueList);
        businessInformationDetailVO.setDateType(dateTypeEnum);

        //  获取目标值  TODO 传工厂
        Double targetValue = screenMapper.monthlyOrderTargetArea();

        //  补全日期
        for (LocalDate date = startDate; !date.isAfter(endDate); ) {
            targetList.add(targetValue);
            Double value = 0D;
            if (dateTypeEnum == DateTypeEnum.DAY) {
                value = dataMap.getOrDefault(date.toString(), 0D);
                dateTimeList.add(date.toString());
                date = date.plusDays(1);
            }
            if (dateTypeEnum == DateTypeEnum.WEEK) {
                value = dataMap.getOrDefault(date.toString(), 0D);
                // 时间格式化
                String startDateStr = date.format(DateTimeFormatter.ofPattern(DateUtils.MM_DD)); // 一周的开始时间
                LocalDate with = date.plusWeeks(1).with(TemporalAdjusters.previousOrSame(DayOfWeek.SUNDAY)); // 一周的最后一天
                String endDateStr = with.format(DateTimeFormatter.ofPattern(DateUtils.MM_DD));
                dateTimeList.add(startDateStr + "--" + endDateStr);
                date = date.plusWeeks(1);
            }
            if (dateTypeEnum == DateTypeEnum.MONTH) {
                String month = String.valueOf(date.getMonth().getValue());
                value = dataMap.getOrDefault(month, 0D);
                dateTimeList.add(month);
                date = date.plusMonths(1);
            }
            valueList.add(value);
        }

        // 填充当天，本周，本月的完成率
        BusinessInformationVO businessInformationVO = this.businessInformation();
        if (null != businessInformationVO) {
            if (businessInformationVO.getOrderList() != null && !businessInformationVO.getOrderList().isEmpty()) {
                List<Double> orderList = businessInformationVO.getOrderList();
                Double yesterdayData = orderList.get(0); // 昨天的值
                Double currentWeekData = orderList.get(1); // 本周的值

                YearMonth yearMonth = YearMonth.now();
                int totalDays = yearMonth.lengthOfMonth();
                Double currentMonthData = orderList.get(2); // 本月的值
                BusinessInformationDetailByFactoryVO.CompletionRateVO completionRateVO = new BusinessInformationDetailByFactoryVO.CompletionRateVO();

                completionRateVO.setYesterday(decimalFormat.format(yesterdayData * 100 / targetValue) + "%");
                completionRateVO.setCurrentWeek(decimalFormat.format(currentWeekData * 100 / (7 * targetValue)) + "%");
                completionRateVO.setCurrentMonth(decimalFormat.format(currentMonthData * 100 / (totalDays * targetValue)) + "%");
                businessInformationDetailVO.setCompletionRateVO(completionRateVO);
            }
        }
        return businessInformationDetailVO;
    }

    private Double getQualityInfo(Map map) {
        if (null == map) {
            return 0D;
        }
        return (Double) map.getOrDefault("qualificationRate", 0D);
    }

    /**
     * 获取所有订单面积
     *
     * @param list 每天的订单面积
     * @return 所有天数的订单面积
     */
    private Double getSumOrderArea(List<Map> list) {
        Double num = 0D;
        for (Map map : list) {
            num += null == map ? 0L : Double.parseDouble(map.getOrDefault(ORDER_AREA_FIELD, 0D).toString());
        }
        return num;
    }

}